﻿using System;
using System.Diagnostics.CodeAnalysis;

namespace ChessKit.Properties
{
  /// <summary>
  /// Specifies that an object has no subproperties capable of being edited. This class cannot be inherited.
  /// </summary>
  [AttributeUsage(AttributeTargets.All)]
  [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)] internal sealed class ImmutableObjectAttribute : Attribute
  {
    /// <summary> Specifies that an object has no subproperties that can be edited. This static field is read-only. </summary>
    [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
      Justification = "In fact immutable")]
    public static readonly ImmutableObjectAttribute Yes = new ImmutableObjectAttribute(true);
    /// <summary> Specifies that an object has at least one editable subproperty. This static field is read-only. </summary>
    [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
      Justification = "In fact immutable")]
    public static readonly ImmutableObjectAttribute No = new ImmutableObjectAttribute(false);
    /// <summary> Represents the default value for <see cref="ImmutableObjectAttribute"/>. </summary>
    [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
      Justification = "In fact immutable")]
    public static readonly ImmutableObjectAttribute Default = No;

    /// <summary>Gets whether the object is immutable. </summary>
    /// <returns>true if the object is immutable; otherwise, false. </returns>
    public bool Immutable { get; private set; }

    /// <summary>Initializes a new instance of the <see cref="ImmutableObjectAttribute"/> class. </summary>
    /// <param name="immutable">true if the object is immutable; otherwise, false. </param>
    public ImmutableObjectAttribute(bool immutable)
    {
      Immutable = immutable;
    }

    /// <returns>true if <paramref name="obj"/> equals the Type and value of this instance; otherwise, false. </returns>
    /// <param name="obj">An <see cref="System.Object"/> to compare with this instance or null. </param>
    public override bool Equals(object obj)
    {
      if (obj == this) return true;
      var immutableObjectAttribute = obj as ImmutableObjectAttribute;
      return immutableObjectAttribute != null && immutableObjectAttribute.Immutable == Immutable;
    }

    /// <summary>Returns the hash code for this instance.</summary>
    /// <returns> A hash code for the current <see cref="ImmutableObjectAttribute"/>. </returns>
    public override int GetHashCode()
    {
      return base.GetHashCode();
    }
  }
}